home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-07-16 | 57.4 KB | 2,188 lines |
- This is an official patch to nn release 6.4
- -------------------------------------------
-
- PATCH #8
-
- Priority: HIGH
-
-
- These patches fix several bugs in the 6.4 release which introduced in
- patch #7 -- sigh! I really goofed that one!
-
- - The new print-header-lines and save-header-lines variables caused
- the print and save-short commands to dump core on some systems.
-
- - It was no longer possible to map keys in the reading mode map to
- simple commands, e.g. map show q next-article.
-
- - An optimization was introduced to avoid opening the "newsgroups"
- file multiple time (by not closing it) - but it was opened multiple
- times anyway without closing any of them.
-
- - It wasn't possible to set the new shading-off/-on variables as
- documented in the manual.
-
-
- A couple of new features are also included in this patch (hopefully
- without introducing more errors this time):
-
- - If a centralized DATA directory is used (i.e. if DB_DIRECTORY and/or
- DB_DATA_DIRECTORY is defined in config.h), it will have reached a
- critical size on many installations. With this patch, the DATA
- directory will be split into subdirectories with 100 groups in each
- directory.
-
- "./inst u" will automatically split DATA into subdirectories if this
- is relevant in your configuration, so you will *not* need to rebuild
- the database after applying this patch!
-
- If for some reason you don't run "./inst u", the DATA directory is
- not reorganized, but nnmaster and nn will recognize this and
- continue to work as usual with the unsplit DATA directory.
-
- If "DB_LONG_NAMES" is defined in config.h, the DATA directory will
- *not* be split (since there is no easy way to do the reorganization).
- (Using long names is probably a bad idea anyway, because the
- directory gets *really big* that way).
-
- - If nnmaster terminates due to a fatal error, a message is now mailed
- to OWNER (see RELEASE_NOTES for more details).
-
- - The back_act program now takes an optional argument specifying how
- many copies of the active file are maintained. See nngoback(1) for
- details.
-
- - The "Control:" and "Sender:" header fields can now be included in
- the customized headers (codes "C" and "f").
-
- - There is a new -ZERO option to nnacct to clear all usage counters.
-
-
- As usual, all changes are described in the updated RELEASE_NOTES file
- (read that for more details about this patch). Thanks to all who
- reported bugs and provided fixes.
-
- To apply this patch, use nn's :patch command, or run this command from
- the shell in the root of the nn source tree:
- patch -p0 < this-article
-
- Then run "make all" and "./inst u".
-
- ++Kim Storm
-
- *** ./LAST/account.c Mon Jul 9 17:59:52 1990
- --- account.c Tue Jul 10 23:30:57 1990
- ***************
- *** 38,43 ****
- --- 38,44 ----
- #include "config.h"
- #include "options.h"
- #include "proto.h"
- + #include <errno.h>
-
- import char *db_directory;
-
- ***************
- *** 135,140 ****
- --- 136,142 ----
- static int new_policy = -1;
- static int new_quota = -1;
- static int who_am_caller = I_AM_ACCT;
- + static char *zero_accounts = NULL;
-
- Option_Description(acct_options) {
- 'C', Int_Option(show_cost),
- ***************
- *** 147,152 ****
- --- 149,155 ----
- 'q', Int_Option(new_quota),
- 'r', Bool_Option(report),
- 'Q', Bool_Option(quiet),
- + 'Z', String_Option(zero_accounts),
- '\0',
- };
-
- ***************
- *** 299,305 ****
- --- 302,353 ----
- }
- }
-
- + static char *ZERO_STAMP = "(Zeroed)";
-
- + static do_zero()
- + {
- + FILE *old, *new;
- + char *acct, bak[FILENAME];
- + struct account ac;
- + extern int errno;
- +
- + acct = relative(db_directory, "acct");
- + old = open_file(acct, OPEN_READ);
- + if (old == NULL) goto err;
- +
- + sprintf(bak, "%s.old", acct);
- + if (unlink(bak) < 0 && errno != ENOENT) goto err;
- + if (link(acct, bak) < 0) goto err;
- + if (unlink(acct) < 0) {
- + unlink(bak);
- + goto err;
- + }
- +
- + umask(0177);
- + new = open_file(acct, OPEN_CREATE);
- + if (new == NULL) goto err2;
- + ac.ac_found = 0;
- + strcpy(ac.ac_user, ZERO_STAMP);
- + ac.ac_total = ac.ac_policy = ac.ac_quota = 0;
- + time(&(ac.ac_last));
- + put_entry(new, &ac);
- +
- + while (get_entry(old, (char *)NULL, &ac)) {
- + if (strcmp(ac.ac_user, ZERO_STAMP) == 0) continue;
- + ac.ac_total = 0;
- + ac.ac_found = 0;
- + put_entry(new, &ac);
- + }
- + fclose(old);
- + if (fclose(new) == EOF) goto err2;
- + return;
- +
- + err2:
- + unlink(acct);
- + if (link(bak, acct) == 0) unlink(bak);
- + err:
- + fprintf(stderr, "ZERO of accounts failed -- check permissions etc.\n");
- + }
-
- main(argc, argv)
- int argc;
- ***************
- *** 317,322 ****
- --- 365,375 ----
-
- users = parse_options(argc, argv, (char *)NULL, acct_options, "");
-
- + if (zero_accounts && strcmp(zero_accounts, "ERO")) {
- + fprintf(stderr, "Must specify -ZERO to clear accounts\n");
- + exit(1);
- + }
- +
- if (user_id != 0) {
- if (report_all) {
- fprintf(stderr, "Only root can request complete reports\n");
- ***************
- *** 330,335 ****
- --- 383,392 ----
- fprintf(stderr, "Only root can change user quotas\n");
- exit(9);
- }
- + if (zero_accounts) {
- + fprintf(stderr, "Only root can zero user accounts\n");
- + exit(9);
- + }
- if (users > 0) {
- fprintf(stderr, "Only root can request reports for other users\n");
- exit(9);
- ***************
- *** 351,357 ****
- add_usage = -1;
- }
-
- ! if (add_usage > 0 || new_policy >= 0 || new_quota >= 0) {
- if (acct_file) {
- fprintf(stderr, "Can only update current acct file\n", acct_file);
- exit(2);
- --- 408,414 ----
- add_usage = -1;
- }
-
- ! if (zero_accounts || add_usage > 0 || new_policy >= 0 || new_quota >= 0) {
- if (acct_file) {
- fprintf(stderr, "Can only update current acct file\n", acct_file);
- exit(2);
- ***************
- *** 358,363 ****
- --- 415,426 ----
- }
-
- proto_lock(I_AM_ACCT, PL_SET_QUICK);
- + }
- +
- + if (zero_accounts) {
- + do_zero();
- + proto_lock(I_AM_ACCT, PL_CLEAR);
- + exit(0);
- }
-
- if (acct_file) {
- *** ./LAST/admin.c Mon Jun 25 15:46:36 1990
- --- admin.c Thu Jul 12 13:00:15 1990
- ***************
- *** 19,24 ****
- --- 19,25 ----
-
- import char *exec_chdir_to;
-
- + import int db_data_subdirs;
-
- static char *pre_input;
- static int verbose = 1;
- ***************
- *** 166,171 ****
- --- 167,175 ----
- printf("Cannot list all files (they are scattered over the news partition)\n");
- return;
- }
- + if (db_data_subdirs)
- + sprintf(command, "cd %s ; ls -l [0-9] | %s", db_data_directory, pager);
- + else
- sprintf(command, "ls -l %s | %s", db_data_directory, pager);
- } else
- sprintf(command, "ls -l %s", db_data_path(name, gh, '*'));
- ***************
- *** 896,904 ****
- news_directory,
- news_lib_directory);
-
- ! printf("DB: %s %s\n", db_directory,
- ! db_data_directory != NULL ? db_data_directory :
- ! "(per-group files in group directories)");
-
- printf("ACTIVE: %s\n", news_active);
-
- --- 900,916 ----
- news_directory,
- news_lib_directory);
-
- ! printf("DB: %s\nDATA: ", db_directory);
- ! if (db_data_directory != NULL) {
- ! #ifdef DB_LONG_NAMES
- ! printf("%s/{group.name}.[dx]\n", db_data_directory);
- ! #else
- ! printf("%s%s/{group-number}.[dx]\n", db_data_directory,
- ! db_data_subdirs ? "/[0-9]" : "");
- ! #endif
- ! } else {
- ! printf("%s/{group/name/path}/.nn[dx]\n", news_directory);
- ! }
-
- printf("ACTIVE: %s\n", news_active);
-
- *** ./LAST/answer.c Mon Jun 25 15:46:38 1990
- --- answer.c Thu Jul 12 00:07:59 1990
- ***************
- *** 9,16 ****
- --- 9,18 ----
- #include "term.h"
- #include "keymap.h"
- #include "options.h"
- + #include "regexp.h"
-
- extern char *temp_file;
- + extern char *news_lib_directory;
-
- export char *default_distribution = NULL;
- export char *extra_mail_headers = NULL;
- ***************
- *** 190,195 ****
- --- 192,268 ----
- return 0;
- }
-
- + /*
- + * open_purpose_file()
- + *
- + * Open "newsgroups" file once - just rewind() otherwise.
- + * Caller must NOT close it!
- + */
- +
- + FILE *open_purpose_file()
- + {
- + static FILE *f = NULL;
- + static int is_open = 0;
- +
- + if (is_open) {
- + if (f != NULL) rewind(f);
- + return f;
- + }
- + is_open = 1;
- +
- + #ifdef NNTP
- + if (use_nntp) {
- + extern FILE *nntp_get_newsgroups();
- + f = nntp_get_newsgroups();
- + } else
- + #endif
- + f = open_file(relative(news_lib_directory, "newsgroups"), OPEN_READ);
- + return f;
- + }
- +
- + /*
- + * display list of group purposes
- + */
- +
- + display_group_list(get_regexp)
- + int get_regexp;
- + {
- + FILE *f;
- + char line[512];
- + extern regexp *pg_regexp;
- + extern int pg_new_regexp;
- + char *expr = NULL;
- +
- + if (get_regexp) {
- + prompt("\1/\1");
- + expr = get_s((char *)NULL, (char *)NULL, (char *)NULL, NULL_FCT);
- + if (expr == NULL || *expr == NUL) return 0;
- + }
- +
- + if ((f = open_purpose_file()) == NULL) return 0;
- + if (who_am_i == I_AM_POST) {
- + gotoxy(0, prompt_line + 1);
- + clrpage(prompt_line + 1);
- + pg_init(prompt_line + 1, 1);
- + } else {
- + home();
- + clrdisp();
- + pg_init(0, 1);
- + }
- + pg_regexp = regcomp(expr);
- +
- + while (fgets(line, 512, f)) {
- + if (pg_regexp && regexec_fold(pg_regexp, line) == 0) continue;
- + if (pg_next() < 0) break;
- + if (pg_new_regexp) {
- + pg_new_regexp = 0; /* pg_next has cleared display */
- + rewind(f);
- + continue;
- + }
- + printf("%s", line);
- + }
- + return 1;
- + }
-
- /*
- * invoke aux shell script with suitable arguments
- ***************
- *** 735,741 ****
- raw();
- clrdisp();
- prompt_line = 0;
- ! post_menu();
- putchar(CR); putchar(NL);
- unset_raw();
- if (*delayed_msg)
- --- 808,814 ----
- raw();
- clrdisp();
- prompt_line = 0;
- ! if (post_menu() == 2) clrdisp();
- putchar(CR); putchar(NL);
- unset_raw();
- if (*delayed_msg)
- ***************
- *** 748,753 ****
- --- 821,829 ----
- {
- register FILE *t, *src;
- register int c;
- + int must_redraw = 0;
- + char brk_chars[4];
- + extern key_type help_key;
- char *str, *tail;
- char group_name[FILENAME], subject[FILENAME],
- distribution[FILENAME], keywords[FILENAME], summary[FILENAME];
- ***************
- *** 770,781 ****
-
- prompt(who_am_i == I_AM_POST ? "Newsgroups: " : "\1POST to group\1 ");
-
- str = get_s(current_group ? current_group->group_name : NONE,
- ! group_name, NONE, group_completion);
- ! if (str == NULL) return 0;
- if (*str == NUL) {
- if (current_group == NULL || (current_group->group_flag & G_FAKED))
- ! return 0;
- str = current_group->group_name;
- }
- strcpy(group_name, str);
- --- 846,866 ----
-
- prompt(who_am_i == I_AM_POST ? "Newsgroups: " : "\1POST to group\1 ");
-
- + strcpy(brk_chars, "??/");
- + brk_chars[0] = help_key;
- str = get_s(current_group ? current_group->group_name : NONE,
- ! group_name, brk_chars, group_completion);
- ! if (str == NULL) goto no_post;
- ! if (*str == '?' || (key_type)(*str) == help_key || *str == '/') {
- ! if (display_group_list(*str == '/'))
- ! must_redraw = 2;
- ! else
- ! msg("No group list is avaialbe");
- ! goto again_group;
- ! }
- if (*str == NUL) {
- if (current_group == NULL || (current_group->group_flag & G_FAKED))
- ! goto no_post;
- str = current_group->group_name;
- }
- strcpy(group_name, str);
- ***************
- *** 792,804 ****
-
- if (tail) *tail++ = ',';
- }
- ! if (who_am_i == I_AM_POST) prompt_line++;
- }
-
- if ((str = post_subject) == NULL) {
- prompt("Subject: ");
- str = get_s(NONE, NONE, NONE, NULL_FCT);
- ! if (str == NULL || *str == NUL) return 0;
- if (who_am_i == I_AM_POST) prompt_line++;
- }
- strcpy(subject, str);
- --- 877,896 ----
-
- if (tail) *tail++ = ',';
- }
- ! if (who_am_i == I_AM_POST) {
- ! prompt_line++;
- ! if (must_redraw) {
- ! gotoxy(0, prompt_line);
- ! clrpage(prompt_line);
- ! must_redraw = 1;
- ! }
- ! }
- }
-
- if ((str = post_subject) == NULL) {
- prompt("Subject: ");
- str = get_s(NONE, NONE, NONE, NULL_FCT);
- ! if (str == NULL || *str == NUL) goto no_post;
- if (who_am_i == I_AM_POST) prompt_line++;
- }
- strcpy(subject, str);
- ***************
- *** 806,812 ****
- if ((str = post_keywords) == NULL) {
- prompt("Keywords: ");
- str = get_s(NONE, NONE, NONE, NULL_FCT);
- ! if (str == NULL) return 0;
- if (who_am_i == I_AM_POST) prompt_line++;
- }
- strcpy(keywords, str);
- --- 898,904 ----
- if ((str = post_keywords) == NULL) {
- prompt("Keywords: ");
- str = get_s(NONE, NONE, NONE, NULL_FCT);
- ! if (str == NULL) goto no_post;
- if (who_am_i == I_AM_POST) prompt_line++;
- }
- strcpy(keywords, str);
- ***************
- *** 814,820 ****
- if ((str = post_summary) == NULL) {
- prompt("Summary: ");
- str = get_s(NONE, NONE, NONE, NULL_FCT);
- ! if (str == NULL) return 0;
- if (who_am_i == I_AM_POST) prompt_line++;
- }
- strcpy(summary, str);
- --- 906,912 ----
- if ((str = post_summary) == NULL) {
- prompt("Summary: ");
- str = get_s(NONE, NONE, NONE, NULL_FCT);
- ! if (str == NULL) goto no_post;
- if (who_am_i == I_AM_POST) prompt_line++;
- }
- strcpy(summary, str);
- ***************
- *** 832,838 ****
-
- prompt("Distribution: (default '%s') ", distribution);
- str = get_s(NONE, NONE, NONE, NULL_FCT);
- ! if (str == NULL) return 0;
- if (*str) strcpy(distribution, str);
- if (who_am_i == I_AM_POST) prompt_line++;
- }
- --- 924,930 ----
-
- prompt("Distribution: (default '%s') ", distribution);
- str = get_s(NONE, NONE, NONE, NULL_FCT);
- ! if (str == NULL) goto no_post;
- if (*str) strcpy(distribution, str);
- if (who_am_i == I_AM_POST) prompt_line++;
- }
- ***************
- *** 840,846 ****
- new_temp_file();
- if ((t = open_file(temp_file, OPEN_CREATE)) == NULL) {
- msg("Can't create %s", temp_file);
- ! return 0;
- }
-
- if (!post_no_edit)
- --- 932,938 ----
- new_temp_file();
- if ((t = open_file(temp_file, OPEN_CREATE)) == NULL) {
- msg("Can't create %s", temp_file);
- ! goto no_post;
- }
-
- if (!post_no_edit)
- ***************
- *** 877,884 ****
- aux_sh((article_header *)NULL, news_script, "post",
- post_no_edit ? "send" : "edit", news_record,
- "Article%s posted", append_sig_post);
-
- ! return 1;
- }
-
- init_answer()
- --- 969,978 ----
- aux_sh((article_header *)NULL, news_script, "post",
- post_no_edit ? "send" : "edit", news_record,
- "Article%s posted", append_sig_post);
- + must_redraw = 1;
-
- ! no_post:
- ! return must_redraw;
- }
-
- init_answer()
- *** ./LAST/back_act.sh Sat Mar 31 23:12:40 1990
- --- back_act.sh Tue Jul 10 21:41:27 1990
- ***************
- *** 8,20 ****
- # It should be invoked by cron every day at midnight.
- # It should run as user `news'!
- #
-
- cd $DB || exit 1
-
- ! p=15
- l=""
- ! for i in 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- do
- if [ -f active.$i ]
- then
- mv active.$i active.$p
- --- 8,23 ----
- # It should be invoked by cron every day at midnight.
- # It should run as user `news'!
- #
- + # Call: back_act [days]
- + # Default: keep copy of active file for the last 14 days.
-
- cd $DB || exit 1
-
- ! p=${1-15}
- l=""
- ! while [ "$p" -gt 0 ]
- do
- + i="`expr $p - 1`"
- if [ -f active.$i ]
- then
- mv active.$i active.$p
- *** ./LAST/db.c Tue May 22 12:53:36 1990
- --- db.c Thu Jul 12 20:53:59 1990
- ***************
- *** 10,15 ****
- --- 10,16 ----
-
- import char
- *master_directory, *db_directory, *db_data_directory, *news_directory;
- + import int db_data_subdirs;
-
- export master_header master;
- export group_header *active_groups = NULL;
- ***************
- *** 530,535 ****
- --- 531,540 ----
- #ifdef DB_LONG_NAMES
- sprintf(namebuf, "%s/%s.%c", db_data_directory, gh->group_name, d_or_x);
- #else
- + if (db_data_subdirs)
- + sprintf(namebuf, "%s/%d/%d.%c", db_data_directory,
- + gh->group_num/100, gh->group_num, d_or_x);
- + else
- sprintf(namebuf, "%s/%d.%c", db_data_directory, gh->group_num, d_or_x);
- #endif
- } else {
- ***************
- *** 569,576 ****
- log_entry('E', "Cannot unlink %s (errno=%d)", data_file, errno);
- f = NULL;
- } else {
- f = open_file(data_file, (mode & ~MUST_EXIST));
- ! if (f == NULL && (mode & MUST_EXIST))
- sys_error("%s (%d): cannot open '%c' file (mode=%x, errno=%d)",
- gh->group_name, (int)(gh->group_num), d_or_x,
- mode, errno);
- --- 574,599 ----
- log_entry('E', "Cannot unlink %s (errno=%d)", data_file, errno);
- f = NULL;
- } else {
- + again:
- f = open_file(data_file, (mode & ~MUST_EXIST));
- ! if (f != NULL) return f;
- ! #ifndef DB_LONG_NAMES
- ! if (db_data_subdirs && (mode&0xf) == OPEN_CREATE && errno == ENOENT) {
- ! char *s;
- ! s = strrchr(data_file, '/');
- ! *s = NUL;
- ! if (!file_exist(data_file, "dx")) {
- ! if (mkdir(data_file, 0755) < 0)
- ! sys_error("Cannot create directory %s", data_file);
- ! log_entry('C', "Created directory %s", data_file);
- ! *s = '/';
- ! goto again;
- ! }
- ! *s = '/';
- ! errno = ENOENT;
- ! }
- ! #endif
- ! if (mode & MUST_EXIST)
- sys_error("%s (%d): cannot open '%c' file (mode=%x, errno=%d)",
- gh->group_name, (int)(gh->group_num), d_or_x,
- mode, errno);
- *** ./LAST/doc/INSTALLATION Tue Jun 12 11:46:29 1990
- --- doc/INSTALLATION Wed Jul 11 21:58:10 1990
- ***************
- *** 550,556 ****
- --- 550,563 ----
- or in /usr/lib/crontab (BSD):
- 00 23 * * * su - news MASTER_DIRECTORY/back_act
-
- + The default setup allows you to go 14 days back with nngoback, but if
- + you don't keep news that long, there is no reason to keep that many
- + copies of the active file either. In that case, you can supply the
- + maximum number of days as an argument to back_act. Of course, you can
- + also keep more than 14 copies of the active file to allow nngoback to
- + go more than 14 days back by giving back_act an argument larger than 14.
-
- +
- STEP 7.4: PREPARE FOR NNSPEW TO BE RUN REGULARLY
- -------------------------------------------------
-
- ***************
- *** 602,607 ****
- --- 609,620 ----
- nnmail is a supported part of nn - if you really want to
- run a domain-based mailer, get smail 2.5 or later. And if you
- ask me how to use it I will answer: "Get SMAIL instead".
- +
- + CLIENT_DIRECTORY/motd
- + Every time you change this file, it will be shown to the nn
- + users the next time they invoke nn. This can be used to
- + inform the users about changes in the news environment or
- + local policies. (motd = message of the day)
-
-
- NNTP_SERVER
- *** ./LAST/doc/RELEASE_NOTES Mon Jul 9 17:59:53 1990
- --- doc/RELEASE_NOTES Mon Jul 16 12:01:59 1990
- ***************
- *** 924,929 ****
- --- 924,972 ----
- From: conrad@zeno.mmwb.ucsf.EDU (Conrad Huang)
- Fixed: Patch #7 [folder.c]
-
- + Prog: nn
- + Title: :print (print-header-type 1) & save-short dumps core [patch #7]
- + From: Mark Nagel <nagel@beaver.ICS.UCI.EDU>
- + ianh@bhpmrl.oz.au (Ian Hoyle)
- + Fixed: Patch #8 [save.c]
- +
- + Prog: nn
- + Title: "map show" cannot bind simple commands [patch #7]
- + From: Jaap Vermeulen <jaap%sequent@relay.EU.net>
- + Fixed: Patch #8 [init.c keymap.c]
- +
- + Prog: nn
- + Title: "newsgroups" file is reopened for each group (w/o close) [patch #7]
- + From: KFS
- + Fixed: Patch #8 [answer.c menu.c]
- +
- + A bug introduced by an attempted optimization in patch #7 - GRRR!
- +
- + Prgog: nn
- + Title: shading-on/-off variables could not be set as documented [patch #7]
- + From: dean@coplex.UUCP (Dean Brooks)
- + Fixed: Patch #8 [variable.c]
- +
- + Prog: nn
- + Title: Cannot define multi-keys #n interactively anymore [patch #7]
- + From: marius@rhi.hi.is (Marius Olafsson)
- + Fixed: Patch #8 [init.c]
- +
- + Prog: nn -g
- + Title: Answer '+' to nn -g prompt gives core dump.
- + From: miller@SCTC.COM (Steven M. Miller)
- + Fixed: Patch #8 [group.c]
- +
- + Prog: nn
- + Title: Cancelled folder articles are counted wrong if cancel attr is cleared
- + From: Stephen Bellantoni <sjb@cs.toronto.edu>
- + Fixed: Patch #8 [folder.c menu.c]
- +
- + Prog: nn
- + Title: Crashes when doing G% in (groups with long names)
- + From: Tony Wilson <wilson@issun3.stc.nl>
- + Fixed: Patch #8 [menu.c -- buffer overrun in get_purpose]
- +
-
- New features since initial 6.4.0 release
- ----------------------------------------
- ***************
- *** 1135,1137 ****
- --- 1178,1254 ----
- Title: New interactive :load command to reload init file (sequence is ignored)
- From: KFS
- Added: Patch #7 [init.c]
- +
- + Prog: nn, nnmaster - database organization
- + Title: DB_DATA is split into subdirs with 100 groups each.
- + From: KFS on request from Scott Merrilees <Sm@soafy.bhpese.oz.au>
- + Added: Patch #8 [admin.c db.c global.c inst.sh prefix.c]
- +
- + See the header of patch 8 for more info. Many thanks to Scott
- + for helping me testing the patch.
- +
- + Prog: nnmaster
- + Title: nnmaster fatal errors are now mailed to OWNER
- + From: KFS on several requests
- + Added: Patch #8 [global.c]
- +
- + The error message is piped into the following command (default):
- + $MAILX -s 'nnmaster fatal error' $OWNER
- + If FATAL_ERROR_MAIL_CMD is defined it will be used instead, e.g.
- + #define FATAL_ERROR_MAIL_CMD "/bin/mail storm"
- +
- + Prog: back_act
- + Title: Number of active copies to keep can now be specified as argument.
- + From: KFS on request from Bruce Fisher <bruce@egh-qc.co.uk>
- + Added: Patch #8 [back_act.sh nngoback.1 INSTALLATION]
- +
- + If news is expired after 7 days, there is no use for 14 days of
- + active files. This can now be reflected in the back_act call:
- + $MASTER/back_act 7
- +
- + Prog: nn
- + Title: Control: (C) and Sender: (f) fields can now be included in header-lines
- + From: KFS on request from karl@ttank.com (Karl Bunch)
- + Added: Patch #8 [news.h news.c more.c nn.1]
- +
- + Prog: nnacct -ZERO
- + Title: New -ZERO option to clear the usage count for all users.
- + From: KFS on request from Claus Dr{by <cld@dkuug.dk>
- + Added: Patch #8 [account.c nnacct.1m]
- +
- + Prog: nn, nnpost
- + Title: nnpost and :post will show newsgroups file if ? is entered
- + From: KFS on request from andrew@cphmlsk.resam.dk (Leif Andrew Rump)
- + Added: Patch #8 [answer.c term.c]
- +
- + If '?' is entered to the "Newsgroup:" prompt, a list of groups
- + and their purpose is displayed.
- + It is possible to search for entries contaning a specific word
- + (really any regular expression), by entering '/expr' to the
- + "Hit any key to continue" prompt.
- +
- + Prog: nn
- + Title: A "message of the day" file is now displayed whenever it changes.
- + From: KFS on request from asd@mace.cc.purdue.edu (Kareth)
- + Added: Patch #8 [nn.c init.c term.c variable.c INSTALLATION nn.1]
- +
- + The file CLIENT/motd will be shown when users start nn and the file
- + has changed since they last started nn. They can inhibit showing
- + the motd file by unsetting the variable "motd", and the file can be
- + shown at any time using the command ":motd".
- +
- + Prog: nn
- + Title: Will now always check .rnlast or age of .newsrc if .nn/LAST not found.
- + From: KFS on request from Peter Andersen
- + Added: Patch #8 [newsrc.c]
- +
- + Converts from other news readers (e.g. rn) will have a .rnlast or at
- + least a .newsrc file which can be used to guess which groups are NEW.
- + This information is now used even when new-groups-action == 3 or 4
- + for new nn users (without a LAST file); before all groups not in
- + .newsrc would be seen as NEW groups.
- +
- + Prog: nn
- + Title: The proper "re prefix" is now also shown on the "*" header in read mode
- + From: Uwe Doering (adapted by KFS)
- + Added: Patch #8 [menu.c more.c variable.c]
- *** ./LAST/folder.c Mon Jul 9 17:59:53 1990
- --- folder.c Wed Jul 11 19:31:56 1990
- ***************
- *** 230,236 ****
- {
- if (ah->attr == A_CANCEL) {
- cancel_count--;
- ! ah->flag = 0;
- } else {
- cancel_count++;
- ah->attr = A_CANCEL;
- --- 230,236 ----
- {
- if (ah->attr == A_CANCEL) {
- cancel_count--;
- ! ah->attr = 0;
- } else {
- cancel_count++;
- ah->attr = A_CANCEL;
- ***************
- *** 371,376 ****
- --- 371,384 ----
- reenter_menu:
- menu_cmd = menu(folder_header);
-
- + if (mode == 0 && cancel_count) {
- + register article_number cur;
- +
- + cancel_count = 0;
- + for (cur = 0; cur < n_articles; cur++) {
- + if (articles[cur]->attr == A_CANCEL) cancel_count++;
- + }
- + }
- if (mode == 0 && cancel_count) {
- clrdisp();
- printf("Folder: %s\nFile: %s\n\n", folder_name, folder_file);
- *** ./LAST/global.c Mon Jun 25 15:46:40 1990
- --- global.c Thu Jul 12 19:45:15 1990
- ***************
- *** 21,26 ****
- --- 21,27 ----
-
- export char *db_directory; /* /usr/spool/nn or NEWS_DIR/.nn */
- export char *db_data_directory; /* ..../DATA or undefined */
- + export int db_data_subdirs = 0; /* set if DATA/[0-9]/ exist */
-
- export char *news_active; /* NLIB/active or DB/ACTIVE */
-
- ***************
- *** 213,218 ****
- --- 214,223 ----
- db_data_directory = NULL;
- #endif
- #endif
- + #ifndef DB_LONG_NAMES
- + if (db_data_directory != NULL)
- + db_data_subdirs = file_exist(relative(db_data_directory, "0"), "dx");
- + #endif
-
- #ifdef NEWS_LIB_DIRECTORY
- news_lib_directory = NEWS_LIB_DIRECTORY;
- ***************
- *** 526,531 ****
- --- 531,556 ----
- return 1;
- }
-
- + static mail_sys_error(err)
- + char *err;
- + {
- + FILE *f;
- + char cmd[FILENAME*2];
- +
- + #ifdef FATAL_ERROR_MAIL_CMD
- + strcpy(cmd, FATAL_ERROR_MAIL_CMD);
- + #else
- + #ifdef MAILX
- + sprintf(cmd, "%s -s 'nnmaster fatal error' %s", MAILX, OWNER);
- + #else
- + sprintf(cmd, "mail %s", OWNER);
- + #endif
- + #endif
- + if ((f = popen(cmd, "w")) == NULL) return;
- + fprintf(f, "nnmaster terminated\n\nFatal system error:\n%s\n", err);
- + pclose(f);
- + }
- +
- /*VARARGS*/
- sys_error(va_alist)
- va_dcl
- ***************
- *** 545,550 ****
- --- 570,576 ----
- end_vararg;
-
- if (who_am_i == I_AM_MASTER) {
- + mail_sys_error(buf);
- if (dont_write_console) nn_exit(7);
- #ifndef HAVE_SYSLOG
- f = open_file("/dev/console", OPEN_CREATE);
- *** ./LAST/group.c Mon Jul 9 17:59:55 1990
- --- group.c Tue Jul 10 23:15:26 1990
- ***************
- *** 767,773 ****
- m_endinput();
- if (strcmp(answer, "+") == 0)
- answer = (gh && gh->save_file != NULL) ? gh->save_file :
- ! (gh->group_flag & G_FOLDER) ? folder_save_file : default_save_file;
- menu_cmd = folder_menu(answer, 0);
- gh = NULL;
- goto goto_exit;
- --- 767,774 ----
- m_endinput();
- if (strcmp(answer, "+") == 0)
- answer = (gh && gh->save_file != NULL) ? gh->save_file :
- ! (gh && gh->group_flag & G_FOLDER) ? folder_save_file :
- ! default_save_file;
- menu_cmd = folder_menu(answer, 0);
- gh = NULL;
- goto goto_exit;
- *** ./LAST/init.c Mon Jul 9 17:59:55 1990
- --- init.c Thu Jul 12 21:58:36 1990
- ***************
- *** 245,250 ****
- --- 245,251 ----
- "man", 3, 0,
- "map", 3, 4,
- "mkdir", 5, 1,
- + "motd", 4, 0,
- "patch", 5, 0, /* QUICK HACK */
- "post", 4, 0, /* QUICK HACK */
- "print", 5, -3, /* QUICK HACK */
- ***************
- *** 362,367 ****
- --- 363,369 ----
-
- case 4:
- /* [map XXX ]Y command[ N] */
- + if (*head == '#') return -1;
- for (p = head, temp = 0; *p; )
- if (*p++ == SP) {
- while (*p && *p == SP) p++;
- ***************
- *** 682,688 ****
- }
-
- if (code == K_UNBOUND && argv(3))
- ! code = lookup_command(argv(3), K_ONLY_MENU);
-
- switch (code) {
- case K_EQUAL_KEY:
- --- 684,690 ----
- }
-
- if (code == K_UNBOUND && argv(3))
- ! code = lookup_command(argv(3), map_def->km_flag & (K_ONLY_MENU|K_ONLY_MORE));
-
- switch (code) {
- case K_EQUAL_KEY:
- ***************
- *** 1059,1064 ****
- --- 1061,1072 ----
- init_group(orig_group);
-
- return AC_REDRAW;
- + }
- +
- + CASE( "motd" ) {
- + if (display_motd(0)) return AC_REDRAW;
- + msg("no motd file");
- + break;
- }
-
- CASE( "sort" ) {
- *** ./LAST/inst.sh Tue Jun 12 11:46:37 1990
- --- inst.sh Mon Jul 16 15:52:45 1990
- ***************
- *** 156,161 ****
- --- 156,168 ----
- then
- OPT="$OPT master"
- fi
- + if $DBSHORTNAME
- + then
- + if [ -n "$DBDATA" -a -d "$DBDATA" -a ! -d "$DBDATA/0" ]
- + then
- + OPT="$OPT splitdb"
- + fi
- + fi
- if [ -f "$BIN/nn" ]
- then
- OPT="$OPT bin"
- ***************
- *** 367,376 ****
- ) &
- ;;
-
- init)
- echo
- ./inst mkdir "$DB" 755 || exit 1
- ! ./inst mkdir "$DBDATA" 755 || exit 1
-
- if $NNTP ; then
- if [ x"$NNTPCACHE" != "x" ] ; then
- --- 374,446 ----
- ) &
- ;;
-
- + splitdb)
- + (
- + echo
- + echo "Rearranging $DBDATA directory for better performance."
- + echo "Notice: If interrupted, the database must be rebuilt!"
- + echo "Be patient. This may take a while...."
- + echo
- +
- + $MASTER/nnmaster -l "DATABASE UPGRADE IN PROGRESS"
- +
- + OLDDB="${DBDATA}-old"
- + mv ${DBDATA} ${OLDDB} || exit 1
- + ./inst mkdir "$DBDATA" 755 || exit 1
- +
- + Ngrp="`cat ${DB}/GROUPS | wc -l`"
- + Ngrp="`expr $Ngrp + 1`"
- + Ndir="`expr $Ngrp / 100`"
- +
- + i=0
- + while [ $i -le $Ndir ]
- + do
- + ./inst mkdir "${DBDATA}/${i}" 755 || exit 1
- + i="`expr $i + 1`"
- + done
- +
- + cd ${OLDDB}
- + i=$Ndir
- + while [ $i -ge 1 ]
- + do
- + if [ "`echo ${i}[0-9][0-9].[dx]`" != "${i}[0-9][0-9].[dx]" ]
- + then
- + echo "Moving groups ${i}00-${i}99 to ${DBDATA}/${i}"
- + mv ${i}[0-9][0-9].[dx] ${DBDATA}/${i}
- + fi
- + i="`expr $i - 1`"
- + done
- + if [ "`echo *.[dx]`" != '*.[dx]' ]
- + then
- + echo "Moving groups 0-99 to ${DBDATA}/${i}"
- + mv *.[dx] ${DBDATA}/0
- + fi
- +
- + cd /tmp
- + rm -r ${OLDDB}
- +
- + $MASTER/nnmaster -l
- +
- + echo "Database reorganization completed."
- + echo
- + )
- + ;;
- +
- init)
- echo
- ./inst mkdir "$DB" 755 || exit 1
- ! if [ -n "$DBDATA" ] ; then
- ! if [ -d "$DBDATA" -a "$DBDATA" = "${DB}/DATA" ]
- ! then
- ! echo "Removing old data files"
- ! ( cd /tmp && rm -r "$DBDATA" )
- ! fi
- ! ./inst mkdir "$DBDATA" 755 || exit 1
- ! if $DBSHORTNAME
- ! then
- ! ./inst mkdir "$DBDATA/0" 755 || exit 1
- ! fi
- ! fi
-
- if $NNTP ; then
- if [ x"$NNTPCACHE" != "x" ] ; then
- ***************
- *** 418,423 ****
- --- 488,494 ----
- expired soon anyway. A value in the range 100-500 should be more than
- enough. If you don't specify a limit, all articles will be collected,
- but it may take quite some time if the min fields are unreliable.
- +
- EOF
- fi
-
- *** ./LAST/keymap.c Mon Jul 9 17:59:56 1990
- --- keymap.c Wed Jul 11 00:04:59 1990
- ***************
- *** 577,586 ****
- if (t < 0)
- j = k-1;
- else {
- ! if (cnmp->cmd_restriction == 0
- ! || (cnmp->cmd_restriction & restriction))
- ! return cnmp->cmd_code;
- ! break;
- }
- }
-
- --- 577,593 ----
- if (t < 0)
- j = k-1;
- else {
- ! switch (restriction) {
- ! case K_ONLY_MENU:
- ! case K_ONLY_MORE:
- ! if (cnmp->cmd_restriction == restriction) break;
- ! case 0:
- ! if (cnmp->cmd_restriction == 0) break;
- ! return K_INVALID;
- ! default:
- ! break;
- ! }
- ! return cnmp->cmd_code;
- }
- }
-
- *** ./LAST/man/nn.1.B Mon Jul 9 17:59:57 1990
- --- man/nn.1.B Mon Jul 16 15:53:11 1990
- ***************
- *** 178,183 ****
- --- 178,190 ----
- list of newsgroups to post to (you cannot enter a space because
- .B space
- is used for group name completion as described below).
- + If you enter \fB?\fP {\fBhelp-key\fP} as the first key, \fInn\fP
- + will show you a list of all available news groups and their purpose.
- + While paging through this list, you can enter \fBq\fP to quit looking
- + at the list. You can also enter \fB/\fP followed by a regular
- + expression (typically a single word) which will cause \fInn\fP to show
- + a (much shorter) list containing only the lines matching the regular
- + expression.
- .LP
- Generally, \fInn\fP will construct a file with a suitable header, optionally
- include a copy of the article in the file with each non-empty line
- ***************
- *** 793,798 ****
- --- 800,811 ----
- \fB:mkdir\fP [ \fIdirectory\fP ]
- Create the directory (and the directories in its path). It will
- prompt for at directory name if the argument is omitted.
- + .TP
- + \fB:motd\fP
- + Show the \fImessage of the day\fP (maintained by the news
- + administrator in the file "motd" in the lib directory. This file is
- + automatically displayed on start-up whenever it changes if the
- + \fBmotd\fP variable is set.
- .TP
- \fB:pwd\fP
- Print path name of current working directory on message line.
- *** ./LAST/man/nn.1.C Mon Jul 9 17:59:58 1990
- --- man/nn.1.C Mon Jul 16 15:53:11 1990
- ***************
- *** 661,666 ****
- --- 661,672 ----
- characters in the received messages using a "cat -v" like format.
- Otherwise, only the printable characters are shown (default).
- .TP
- + \fBmotd\fP (boolean, default true)
- + When set, \fInn\fP will display the \fImessage of the day\fP on
- + start-up if it has changed since it was last shown. The message is
- + taken from the file "motd" in the lib directory. It can also be shown
- + (again) using the \fB:motd\fP command.
- + .TP
- \fBnew-group-action\fP \fIaction\fP (integer, default 3)
- This variable controls how new groups are treated by \fInn\fP. It is
- an integer variable, and the following values can be used. Some of
- *** ./LAST/man/nn.1.D Mon Jul 9 17:59:59 1990
- --- man/nn.1.D Mon Jul 16 15:53:11 1990
- ***************
- *** 34,44 ****
- --- 34,48 ----
- .br
- \fBB\fP Distribution:
- .br
- + \fBC\fP Control:
- + .br
- \fBD\fP Date:
- .br
- \fBd\fP Date-Received:
- .br
- \fBF\fP From:
- + .br
- + \fBf\fP Sender:
- .br
- \fBG\fP Newsgroup: (current group)
- .br
- *** ./LAST/man/nnacct.1m Tue Apr 24 00:58:50 1990
- --- man/nnacct.1m Thu Jul 12 15:22:42 1990
- ***************
- *** 6,11 ****
- --- 6,13 ----
- \fBnnacct\fP \-\fBr\fP [ \-\fBf\fP file ] [ \-\fBa\fP ] [ user ]...
- .br
- \fBnnacct\fP \-\fBp\fP\fIpolicy\fP \-\fBq\fP\fIquota\fP user...
- + .br
- + \fBnnacct\fP \-\fBZERO\fP
- .SH DESCRIPTION
- The \fInnacct\fP command provides an optional accounting and access
- authorization for news reading via the \fInn\fP news reader.
- ***************
- *** 26,31 ****
- --- 28,38 ----
- given user is not already known in the accounting file, a new entry
- with the specified policy and quota is created (default values are
- used if both are not specified).
- + .LP
- + The third form (\-\fBZERO\fP) will clear the usage counts for
- + \fIall\fP users.
- + Individual usage counts cannot be cleared.
- + The original accounting file is saved with a .old suffix.
- .LP
- The following policies are currently implemented:
- .TP
- *** ./LAST/man/nngoback.1 Wed May 16 11:23:49 1990
- --- man/nngoback.1 Tue Jul 10 22:13:31 1990
- ***************
- *** 61,66 ****
- --- 61,67 ----
- Mark the articles which have arrived during the last week as unread.
- .LP
- You cannot go more than 14 days back with \fInngoback\fP.
- + (You can change this limit as described below.)
- .SH THE BACK_ACT DAEMON
- It is a prerequisite for the use of \fInngoback\fP that the script
- \fBback_act\fP is executed at an appropriate time once (and only once)
- ***************
- *** 67,72 ****
- --- 68,78 ----
- every day. Preferably this is done by \fBcron\fP right before the
- bacth of news for `today' is received. \fBback_act\fP will maintain
- copies of the active file for the last 14 days.
- + .LP
- + Optionally, the \fBback_act\fP program accepts a single numerical
- + argument specifying how many copies of the active file it should
- + maintain. This is useful if news is expired after 7 days, in which
- + case keeping more than 7 days of active file copies is wasteful.
- .SH FILES
- .DT
- .ta \w'~/.newsrc.goback'u+5m
- *** ./LAST/man/nnpost.1 Tue Apr 24 17:31:39 1990
- --- man/nnpost.1 Wed Jul 11 23:49:04 1990
- ***************
- *** 21,26 ****
- --- 21,35 ----
- of the article. Each of these prompts can also be supplied via
- command line options or arguments as described below.
- .LP
- + When prompted for the "Newsgroup:", entering a \fB?\fP as the first
- + key will cause \fInnpost\fP to list all the known news groups and
- + their purpose (if this information is available). You can also enter
- + \fB/\fP followed by a word or regular expression which will cause
- + \fInnpost\fP to produce a (much) shorter listing only containing the
- + groups whose name and/or purpose description matches the regular
- + expression. When paging through either list, you can enter \fBq\fP to
- + quit the listing.
- + .LP
- If a source file is specified with \fB\-f\fP it will be used as the
- initial article body. If the \fB\-p\fP option is also specified, the
- article is posted directly without editing.
- *** ./LAST/menu.c Mon Jul 9 18:00:01 1990
- --- menu.c Mon Jul 16 11:49:34 1990
- ***************
- *** 66,72 ****
-
- char attributes[30] = " .,+=#! **"; /* Corresponds to A_XXXX in data.h */
-
- ! static prt_replies(level)
- {
- int re;
-
- --- 66,72 ----
-
- char attributes[30] = " .,+=#! **"; /* Corresponds to A_XXXX in data.h */
-
- ! prt_replies(level)
- {
- int re;
-
- ***************
- *** 606,635 ****
- static get_purpose(purpose)
- char *purpose;
- {
- ! static FILE *f = NULL;
- ! static not_avail = 0;
- ! char line[256], group[80];
- register char *cp, *pp;
- register int len;
-
- ! if (not_avail) return;
- ! #ifdef NNTP
- ! if (use_nntp) {
- ! extern FILE *nntp_get_newsgroups();
- ! f = nntp_get_newsgroups();
- ! } else
- ! #endif
- ! f = open_file(relative(news_lib_directory, "newsgroups"), OPEN_READ);
- ! if (f == NULL) {
- ! not_avail = 1;
- ! return;
- ! }
- ! rewind(f);
-
- ! sprintf(group, "%s\t", current_group->group_name);
- ! len = current_group->group_name_length + 1;
-
- while (fgets(line, 256, f) != NULL) {
- if (strncmp(line, group, len)) continue;
- cp = line + len;
- while (*cp && isspace(*cp)) cp++;
- --- 606,627 ----
- static get_purpose(purpose)
- char *purpose;
- {
- ! FILE *f, *open_purpose_file();
- ! char line[256], *group;
- register char *cp, *pp;
- register int len;
-
- ! if (current_group == NULL) return;
- ! if ((current_group->master_flag & M_VALID) == 0) return;
- ! if (current_group->group_flag & G_FAKED) return;
-
- ! if ((f = open_purpose_file()) == NULL) return;
- !
- ! group = current_group->group_name;
- ! len = current_group->group_name_length;
-
- while (fgets(line, 256, f) != NULL) {
- + if (!isascii(line[len]) || !isspace(line[len])) continue;
- if (strncmp(line, group, len)) continue;
- cp = line + len;
- while (*cp && isspace(*cp)) cp++;
- ***************
- *** 970,976 ****
-
- if (cur_k_cmd == K_CANCEL) {
- if (current_group->group_flag & G_FOLDER) {
- ! if (ah->attr != A_CANCEL) fcancel(ah);
- } else
- switch (cancel(ah)) {
- case -1:
- --- 962,968 ----
-
- if (cur_k_cmd == K_CANCEL) {
- if (current_group->group_flag & G_FOLDER) {
- ! fcancel(ah);
- } else
- switch (cancel(ah)) {
- case -1:
- *** ./LAST/more.c Mon Jul 9 18:00:03 1990
- --- more.c Mon Jul 16 11:49:34 1990
- ***************
- *** 25,30 ****
- --- 25,31 ----
- export int expired_msg_delay = 1;
- export char *trusted_escapes = NULL;
- export int new_read_prompt = 1;
- + export int re_layout_more = -1;
-
- import int preview_window;
- import int novice;
- ***************
- *** 70,77 ****
- --- 71,80 ----
- } header_defs[] = {
- 'A', "Approved", &news.ng_appr, 0,
- 'B', "Distribution",&news.ng_dist, 0,
- + 'C', "Control", &news.ng_control, 0,
- 'D', "Date", &news.ng_date, &digest.dg_date,
- 'F', "From", &news.ng_from, &digest.dg_from,
- + 'f', "Sender", &news.ng_sender, 0,
- 'I', "Message-Id", &news.ng_ident, 0,
- 'K', "Keywords", &news.ng_keyw, 0,
- 'L', "Lines", &news.ng_xlines, 0,
- ***************
- *** 320,326 ****
- --- 323,343 ----
- if (preview_window < 1 && Lines - screen_offset < min_pv_window)
- screen_offset = 0;
- else {
- + #ifdef notdef
- so_printxy(0, screen_offset++, "%s: %s ", ah->sender, ah->subject);
- + #else
- + import int re_layout;
- + int o_re_layout;
- +
- + so_gotoxy(0, screen_offset++, 0);
- + so_printf("%s: ", ah->sender);
- + o_re_layout = re_layout;
- + if (re_layout_more >= 0) re_layout = re_layout_more;
- + prt_replies(ah->replies);
- + re_layout = o_re_layout;
- + so_printf("%s", ah->subject);
- + so_end();
- + #endif
- if (!STANDOUT) screen_offset++;
- clrline();
- }
- *** ./LAST/news.c Tue Jun 12 11:46:57 1990
- --- news.c Tue Jul 10 22:29:43 1990
- ***************
- *** 128,133 ****
- --- 128,138 ----
- check("ack-References:", 15, ng_bref);
- break;
-
- + case 'C':
- + case 'c':
- + check("ontrol:", 7, ng_control);
- + break;
- +
- case 'D':
- case 'd':
- check("ate:", 4, ng_date);
- ***************
- *** 193,200 ****
- case 'S':
- case 's':
- check("ubject:", 7, ng_subj);
- ! if (news.ng_from == NULL)
- ! check("ender:", 6, ng_from);
- if (!all) break;
- check("ummary:", 7, ng_summ);
- break;
- --- 198,204 ----
- case 'S':
- case 's':
- check("ubject:", 7, ng_subj);
- ! check("ender:", 6, ng_sender);
- if (!all) break;
- check("ummary:", 7, ng_summ);
- break;
- ***************
- *** 271,276 ****
- --- 275,281 ----
- news.ng_groups = NULL;
- news.ng_ref = NULL;
- news.ng_bref = NULL;
- + news.ng_sender = NULL;
-
- news.ng_xlines = NULL;
-
- ***************
- *** 284,289 ****
- --- 289,295 ----
- news.ng_org = NULL;
- news.ng_appr = NULL;
- news.ng_summ = NULL;
- + news.ng_control = NULL;
- news.ng_date = NULL;
- news.ng_rdate = NULL;
- }
- ***************
- *** 294,299 ****
- --- 300,306 ----
- body = parse_header(f, art_hdr_field, modes, buffer1);
-
- news.ng_lines = news.ng_xlines ? atoi(news.ng_xlines) : -1;
- + if (news.ng_from == NULL) news.ng_from = news.ng_sender;
-
- if (modes & FILL_OFFSETS) {
- art->fpos = news.ng_fpos = ftell(f);
- *** ./LAST/news.h Wed May 2 00:03:37 1990
- --- news.h Tue Jul 10 22:29:43 1990
- ***************
- *** 27,32 ****
- --- 27,34 ----
- char *ng_org; /* organization */
- char *ng_appr; /* approved */
- char *ng_summ; /* summary */
- + char *ng_control; /* control */
- + char *ng_sender; /* sender */
-
- char *ng_date; /* date */
-
- *** ./LAST/newsrc.c Mon Jun 25 15:46:50 1990
- --- newsrc.c Thu Jul 12 17:52:14 1990
- ***************
- *** 184,189 ****
- --- 184,190 ----
- FILE *lf = NULL;
- char buf[FILENAME];
- register int i;
- + time_t t;
-
- if (new_group_action == RCX_RNLAST) {
- rnlast_path = home_relative(".rnlast");
- ***************
- *** 195,204 ****
- rnlast_line[i] = copy_str(buf);
- }
- if (i != MAX_RNLAST_LINE) {
- ! printf(".rnlast only supported with active.times patches\n");
- ! sleep(3);
- ! new_group_action = RCX_TIME_CONF;
- ! goto no_file;
- }
- fclose(lf);
- return (time_t)atol(rnlast_line[RN_LAST_CREATION_TIME]);
- --- 196,207 ----
- rnlast_line[i] = copy_str(buf);
- }
- if (i != MAX_RNLAST_LINE) {
- ! while (i <= MAX_RNLAST_LINE) {
- ! rnlast_line[i] = copy_str("");
- ! i++;
- ! }
- ! fclose(lf);
- ! return (time_t)atol(rnlast_line[RN_LAST_TIME_RUN]);
- }
- fclose(lf);
- return (time_t)atol(rnlast_line[RN_LAST_CREATION_TIME]);
- ***************
- *** 213,219 ****
-
- no_file:
- if (lf != NULL) fclose(lf);
- ! return (time_t)(-1);
- }
-
- static update_last_new(lastg)
- --- 216,223 ----
-
- no_file:
- if (lf != NULL) fclose(lf);
- ! t = file_exist(newsrc_file, (char *)NULL);
- ! return t > 0 ? t : (time_t)(-1);
- }
-
- static update_last_new(lastg)
- ***************
- *** 396,403 ****
- case RCX_TIME:
- case RCX_TIME_CONF:
- case RCX_RNLAST:
- ! if (last_new_group == 0)
- last_new_group = get_last_new();
-
- if (gh->creation_time <= last_new_group) {
- /* old groups not in .newsrc are unsubscribed */
- --- 400,415 ----
- case RCX_TIME:
- case RCX_TIME_CONF:
- case RCX_RNLAST:
- ! if (last_new_group == 0) {
- last_new_group = get_last_new();
- + if (last_new_group < 0 && new_group_action != RCX_RNLAST) {
- + /* maybe this is a first time rn convert ? */
- + int nga = new_group_action;
- + new_group_action = RCX_RNLAST;
- + last_new_group = get_last_new();
- + new_group_action = nga;
- + }
- + }
-
- if (gh->creation_time <= last_new_group) {
- /* old groups not in .newsrc are unsubscribed */
- *** ./LAST/nn.c Mon Jul 9 18:00:03 1990
- --- nn.c Thu Jul 12 18:43:28 1990
- ***************
- *** 32,37 ****
- --- 32,38 ----
- export int
- article_limit = -1,
- also_read_articles = 0,
- + batch_mode = 0,
- conf_auto_quit = 0,
- do_kill_handling = 1,
- group_name_args = 0,
- ***************
- *** 38,43 ****
- --- 39,45 ----
- merged_menu = 0,
- repeat_group_query = 0,
- report_cost_on_exit = 1,
- + show_motd_on_entry = 1,
- silent = 0,
- verbose = 0,
- Debug = 0;
- ***************
- *** 529,534 ****
- --- 531,571 ----
- return 0;
- }
-
- + static prt_version()
- + {
- + printf("Release %s, Kim F. Storm, 1990\n\n", version_id);
- + }
- +
- + display_motd(check)
- + int check;
- + {
- + time_t last_motd, cur_motd;
- + char *dot_motd, motd[FILENAME];
- +
- + strcpy(motd, relative(lib_directory, "motd"));
- + cur_motd = file_exist(motd, (char *)NULL);
- + if (cur_motd == 0) return 0;
- +
- + if (!check) {
- + display_file(motd, CLEAR_DISPLAY | CONFIRMATION);
- + return 1;
- + }
- +
- + dot_motd = relative(nn_directory, ".motd");
- + last_motd = file_exist(dot_motd, (char *)NULL);
- +
- + if (last_motd >= cur_motd) return 0;
- +
- + fclose(open_file(dot_motd, OPEN_CREATE|MUST_EXIST));
- +
- + clrdisp();
- +
- + so_printxy(0, 0, "Message of the day");
- + gotoxy(0, 2); prt_version();
- +
- + display_file(motd, CONFIRMATION);
- + return 1;
- + }
-
- clean_group(gh)
- group_header *gh;
- ***************
- *** 583,594 ****
- } else
- if (strcmp(pname, "nnpost") == 0) {
- who_am_i = I_AM_POST;
- } else {
- who_am_i = I_AM_NN;
- }
-
- if (who_am_i == I_AM_NN || (who_am_i == I_AM_ADMIN && argc == 1)) {
- ! if (!isatty(0)) {
- if (who_am_i == I_AM_NN && argc == 2) {
- if (strcmp(argv[1], "-SPEW") == 0) {
- who_am_i = I_AM_SPEW;
- --- 620,635 ----
- } else
- if (strcmp(pname, "nnpost") == 0) {
- who_am_i = I_AM_POST;
- + } else
- + if (strcmp(pname, "nnbatch") == 0) {
- + who_am_i = I_AM_NN;
- + batch_mode = 1;
- } else {
- who_am_i = I_AM_NN;
- }
-
- if (who_am_i == I_AM_NN || (who_am_i == I_AM_ADMIN && argc == 1)) {
- ! if (!batch_mode && !isatty(0)) {
- if (who_am_i == I_AM_NN && argc == 2) {
- if (strcmp(argv[1], "-SPEW") == 0) {
- who_am_i = I_AM_SPEW;
- ***************
- *** 632,638 ****
- #endif
-
- if ((say_welcome = init_global()) < 0) {
- ! printf("%s: nn must been invoked to initialize user files\n", pname);
- nn_exit(1);
- }
-
- --- 673,679 ----
- #endif
-
- if ((say_welcome = init_global()) < 0) {
- ! printf("%s: nn has not been invoked to initialize user files\n", pname);
- nn_exit(1);
- }
-
- ***************
- *** 661,666 ****
- --- 702,712 ----
- }
-
- visit_init_file(0, argv[1]);
- +
- + if (show_motd_on_entry)
- + if (display_motd(1))
- + silent = 1;
- +
- init_answer();
-
- group_name_args =
- ***************
- *** 762,768 ****
- }
-
- if (!silent && who_am_i != I_AM_CHECK)
- ! printf("Release %s, Kim F. Storm, 1990\n\n", version_id);
-
- if (nn_locked()) nn_exit(2);
-
- --- 808,814 ----
- }
-
- if (!silent && who_am_i != I_AM_CHECK)
- ! prt_version();
-
- if (nn_locked()) nn_exit(2);
-
- *** ./LAST/patchlevel.h Mon Jul 9 18:00:04 1990
- --- patchlevel.h Mon Jul 16 12:22:43 1990
- ***************
- *** 18,24 ****
- * 1990-06-11: Patch #5 (6.4.5) - MEDIUM
- * 1990-06-25: Patch #6 (6.4.6) - MEDIUM
- * 1990-07-09: Patch #7 (6.4.7) - LOW
- */
-
- ! #define PATCHLEVEL 7
-
- --- 18,25 ----
- * 1990-06-11: Patch #5 (6.4.5) - MEDIUM
- * 1990-06-25: Patch #6 (6.4.6) - MEDIUM
- * 1990-07-09: Patch #7 (6.4.7) - LOW
- + * 1990-07-16: Patch #8 (6.4.8) - HIGH
- */
-
- ! #define PATCHLEVEL 8
-
- *** ./LAST/prefix.c Wed May 2 21:19:42 1990
- --- prefix.c Thu Jul 12 19:27:22 1990
- ***************
- *** 74,79 ****
- --- 74,84 ----
- fprintf(f, "MASTER=%s\n", master_directory);
- fprintf(f, "HELP=%s\n", help_directory);
- fprintf(f, "DBDATA=\"%s\"\n", db_data_directory ? db_data_directory : "");
- + #ifdef DB_LONG_NAMES
- + fprintf(f, "DBSHORTNAME=false\n");
- + #else
- + fprintf(f, "DBSHORTNAME=true\n");
- + #endif
- fprintf(f, "OWNER=%s%c", OWNER, nl);
- fprintf(f, "GROUP=%s\n", GROUP);
- }
- *** ./LAST/save.c Mon Jul 9 18:00:05 1990
- --- save.c Tue Jul 10 10:32:30 1990
- ***************
- *** 508,514 ****
- } else
- if (mode == SHORT_HEADER || mode == SHORT_HEADER_DG) {
- char *name, *val;
- ! scan_header_fields(short_header_lines, ah->flag & A_DIGEST);
- while (next_header_field(&name, &val, (fct_type *)NULL)) {
- if (name == NULL) continue;
- fprintf(save_file, "%s: %s\n", name, val);
- --- 508,514 ----
- } else
- if (mode == SHORT_HEADER || mode == SHORT_HEADER_DG) {
- char *name, *val;
- ! scan_header_fields(short_header_lines, ah);
- while (next_header_field(&name, &val, (fct_type *)NULL)) {
- if (name == NULL) continue;
- fprintf(save_file, "%s: %s\n", name, val);
- *** ./LAST/term.c Mon Jun 25 15:46:52 1990
- --- term.c Wed Jul 11 21:58:11 1990
- ***************
- *** 9,14 ****
- --- 9,15 ----
- #include "config.h"
- #include "term.h"
- #include "keymap.h"
- + #include "regexp.h"
-
- #ifdef RESIZING
- #include <sys/ioctl.h> /* for TIOCGWINSZ */
- ***************
- *** 21,26 ****
- --- 22,28 ----
- #endif
-
- import int data_bits;
- + import int batch_mode;
-
- struct msg_list {
- char *buf;
- ***************
- *** 313,318 ****
- --- 315,325 ----
- char tbuf[1024];
- #endif
-
- + if (batch_mode) {
- + term_name = "batch";
- + return;
- + }
- +
- if ((term_name = getenv("TERM")) == NULL)
- user_error("No TERM variable in environment");
-
- ***************
- *** 845,850 ****
- --- 852,860 ----
- return K_interrupt;
- }
-
- + if (batch_mode)
- + user_error("Attempt to read keyboard input in batch mode");
- +
- for (i = multi_keys, mk = multi_key_list; --i >= 0; mk++)
- mk->cur_key = mk->keys;
- key_cnt = 0;
- ***************
- *** 1332,1338 ****
-
- chain:
-
- ! f = open_file(relative(help_directory, name), OPEN_READ);
- if (f == NULL)
- printf("\r\n\nFile %s is not available\n\n", name);
- else {
- --- 1342,1349 ----
-
- chain:
-
- ! if (*name != '/') name = relative(help_directory, name);
- ! f = open_file(name, OPEN_READ);
- if (f == NULL)
- printf("\r\n\nFile %s is not available\n\n", name);
- else {
- ***************
- *** 1650,1659 ****
- --- 1661,1678 ----
-
-
- static pg_fline, pg_width, pg_maxw, pg_line, pg_col, pg_quit;
- + export regexp *pg_regexp = NULL;
- + export int pg_new_regexp = 0;
-
- pg_init(first_line, cols)
- int first_line, cols;
- {
- + if (pg_regexp) {
- + freeobj(pg_regexp);
- + pg_regexp = NULL;
- + }
- + pg_new_regexp = 0;
- +
- pg_fline = first_line;
- pg_line = pg_fline - 1;
- pg_quit = pg_col = 0;
- ***************
- *** 1684,1689 ****
- --- 1703,1720 ----
- gotoxy(pg_col, pg_line);
- if (pg_line == Lines - 1 && pg_col == pg_maxw) {
- c = any_key(0);
- + if (c == '/') {
- + char *expr;
- + putchar(CR);
- + putchar('/');
- + clrline();
- + expr = get_s((char *)NULL, (char *)NULL, (char *)NULL, NULL_FCT);
- + if (expr != NULL && *expr != NUL) {
- + freeobj(pg_regexp);
- + pg_regexp = regcomp(expr);
- + pg_new_regexp = 1;
- + }
- + }
- gotoxy(0, pg_fline);
- clrpage(pg_fline);
- pg_col = 0;
- ***************
- *** 1712,1717 ****
- --- 1743,1753 ----
- {
- if (pg_quit == 0 && pg_next() == 0)
- any_key(0);
- +
- + if (pg_regexp) {
- + freeobj(pg_regexp);
- + pg_regexp = NULL;
- + }
- }
-
-
- *** ./LAST/variable.c Mon Jul 9 18:00:05 1990
- --- variable.c Mon Jul 16 12:09:36 1990
- ***************
- *** 6,11 ****
- --- 6,12 ----
-
- #include "config.h"
- #include "keymap.h"
- + #include "regexp.h"
-
- import in_init;
-
- ***************
- *** 109,114 ****
- --- 110,116 ----
- shell_restrictions,
- show_article_date,
- show_current_time,
- + show_motd_on_entry,
- silent,
- slow_mode,
- suggest_save_file,
- ***************
- *** 149,154 ****
- --- 151,157 ----
- preview_window,
- print_header_type,
- re_layout,
- + re_layout_more,
- response_check_pause,
- retry_on_error,
- save_counter_offset,
- ***************
- *** 178,183 ****
- --- 181,187 ----
- #undef SPEC
- #undef SAFE
- #undef INIT
- + #undef CODES
-
-
- #define V_STRING 0x1000
- ***************
- *** 185,190 ****
- --- 189,195 ----
- #define V_INTEGER 0x3000
- #define V_KEY 0x4000
- #define V_SPECIAL 0x5000
- + #define V_CODES 0x6000
-
- #define V_SAFE 0x0100
- #define V_INIT 0x0200
- ***************
- *** 196,205 ****
- --- 201,216 ----
- #define INT V_INTEGER |
- #define KEY V_KEY |
- #define SPEC V_SPECIAL |
- + #define CODES V_CODES |
-
- #define SAFE V_SAFE |
- #define INIT V_INIT |
-
- + static char *code_strings[16] = {
- + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
- + };
- +
- struct variable_defs {
- char *var_name;
- int var_flags;
- ***************
- *** 289,294 ****
- --- 300,306 ----
- "min-window", INT 1, (char **)&min_pv_window,
- "mmdf-format", BOOL 0, (char **)&use_mmdf_folders,
- "monitor", BOOL 0, (char **)&monitor_mode,
- + "motd", BOOL 0, (char **)&show_motd_on_entry,
- "new-group-action", INT 0, (char **)&new_group_action,
- "new-style-read-prompt", BOOL 0, (char **)&new_read_prompt,
- "news-header", STR 0, (char **)&extra_news_headers,
- ***************
- *** 315,320 ****
- --- 327,333 ----
- "quick-count", BOOL 0, (char **)&quick_unread_count,
- "quick-save", BOOL 0, (char **)&quick_save,
- "re-layout", INT 0, (char **)&re_layout,
- + "re-layout-read", INT 0, (char **)&re_layout_more,
- "read-return-next-page", BOOL 0, (char **)&read_ret_next_page,
- "record", SPEC 1, (char **)NULL,
- "repeat", BOOL 0, (char **)&fmt_rptsubj,
- ***************
- *** 331,338 ****
- "scroll-clear-page", BOOL 0, (char **)&scroll_clear_page,
- "select-leave-next", BOOL 0, (char **)&select_leave_next,
- "select-on-sender", BOOL 0, (char **)&select_on_sender,
- ! "shading-off", STR 0, (char **)&shade_off_attr,
- ! "shading-on", STR 0, (char **)&shade_on_attr,
- "shell", STR SAFE 0, (char **)&user_shell,
- "shell-restrictions", BOOL INIT 0, (char **)&shell_restrictions,
- "show-purpose-mode", INT 0, (char **)&show_purpose_mode,
- --- 344,351 ----
- "scroll-clear-page", BOOL 0, (char **)&scroll_clear_page,
- "select-leave-next", BOOL 0, (char **)&select_leave_next,
- "select-on-sender", BOOL 0, (char **)&select_on_sender,
- ! "shading-off", CODES 0, (char **)&shade_off_attr,
- ! "shading-on", CODES 1, (char **)&shade_on_attr,
- "shell", STR SAFE 0, (char **)&user_shell,
- "shell-restrictions", BOOL INIT 0, (char **)&shell_restrictions,
- "show-purpose-mode", INT 0, (char **)&show_purpose_mode,
- ***************
- *** 591,596 ****
- --- 604,642 ----
- article_limit = (on && value > 0) ? value : -1;
- break;
- }
- +
- + case V_CODES:
- + {
- + char codes[80], code[16], *sp, *cp, *vs;
- +
- + if (val_string == NULL) on = 0;
- + if (on) {
- + adjust(val_string);
- + if (val_string[0] == NUL) on = 0;
- + }
- +
- + if (on) {
- + sp = codes;
- + vs = val_string;
- + while (*vs) {
- + while (*vs && (!isascii(*vs) || isspace(*vs)))
- + vs++;
- + if (*vs == NUL) break;
- + cp = code;
- + while (*vs && isascii(*vs) && !isspace(*vs))
- + *cp++ = *vs++;
- + *cp = NUL;
- + *sp++ = parse_key(code);
- + }
- + *sp = NUL;
- + if (codes[0] == NUL) on = 0;
- + }
- +
- + freeobj(code_strings[VAR_OP]);
- + code_strings[VAR_OP] = on ? copy_str(val_string) : NULL;
- + STR_VAR = on ? copy_str(codes) : (char *)NULL;
- + break;
- + }
- break;
- }
- return 0;
- ***************
- *** 652,657 ****
- --- 698,707 ----
- break;
- }
- break;
- +
- + case V_CODES:
- + str = code_strings[VAR_OP];
- + break;
- }
- if (str == NULL) str = "NULL";
- return str;
- ***************
- *** 843,848 ****
- --- 893,902 ----
- case V_SPECIAL:
- msg("Cannot push pseudo variable %s", var->var_name);
- break;
- +
- + case V_CODES:
- + msg("Cannot push code string variable %s", var->var_name);
- + break;
- }
-
- return 1;
- ***************
- *** 900,905 ****
- --- 954,962 ----
-
- case V_SPECIAL: /* these are not saved, so... */
- break;
- +
- + case V_CODES:
- + break;
- }
-
- vs1 = vs->next;
- ***************
- *** 926,931 ****
- --- 983,990 ----
- char *str, pushed;
- int b;
- register struct variable_defs *var;
- + extern regexp *pg_regexp;
- + extern int pg_new_regexp;
-
- if (in_init) return;
-
- ***************
- *** 940,995 ****
- so_printf("Variable settings:");
-
- for (var = variables; var < &variables[TABLE_SIZE]; var++) {
- ! pushed =
- ! var_on_stack(var) ? '>' :
- ! (var->var_flags & V_MODIFIED) ? '*' : ' ';
- !
- if (!all && pushed == ' ') continue;
- !
- ! switch (VAR_TYPE) {
- ! case V_STRING:
- ! if (pg_next() < 0) goto out;
- ! str = (VAR_OP == 1) ? CBUF_VAR : STR_VAR;
- ! if (str == NULL) str = "";
- ! printf("%c %-20.20s = \"%s\"\n", pushed, var->var_name, str);
- ! break;
- !
- ! case V_BOOLEAN:
- ! if (pg_next() < 0) goto out;
- ! b = BOOL_VAR;
- ! if (VAR_OP == 2 || VAR_OP == 4) b = !b;
- ! printf("%c %-20.20s = %s\n",
- ! pushed, var->var_name, b ? "on" : "off");
- ! break;
- !
- ! case V_INTEGER:
- ! if (pg_next() < 0) goto out;
- ! printf("%c %-20.20s = %d\n", pushed, var->var_name, INT_VAR);
- ! break;
- !
- ! case V_KEY:
- ! if (pg_next() < 0) goto out;
- ! printf("%c %-20.20s = %s\n",
- ! pushed, var->var_name, key_name(KEY_VAR));
- ! break;
- !
- ! case V_SPECIAL:
- ! switch (VAR_OP) {
- ! case 1:
- ! break;
- ! case 2:
- ! if (also_read_articles) {
- ! if (pg_next() < 0) goto out;
- ! printf("%c %-20.20s = %d\n",
- ! pushed, var->var_name, article_limit);
- ! }
- ! break;
- ! }
- ! break;
- }
- }
-
- - out:
- pg_end();
- }
-
- --- 999,1021 ----
- so_printf("Variable settings:");
-
- for (var = variables; var < &variables[TABLE_SIZE]; var++) {
- ! if (pg_regexp != NULL && regexec(pg_regexp, var->var_name) == 0)
- ! continue;
- ! str = var_value(var, &pushed);
- if (!all && pushed == ' ') continue;
- ! if (pg_next() < 0) break;
- ! if (pg_new_regexp) {
- ! pg_new_regexp = 0;
- ! var = variables;
- ! var--;
- ! continue;
- }
- + if (VAR_TYPE == V_STRING)
- + printf("%c %-25.25s = \"%s\"\n", pushed, var->var_name, str);
- + else
- + printf("%c %-25.25s = %s\n", pushed, var->var_name, str);
- }
-
- pg_end();
- }
-
-